from PyQt5.Qt import *
from widget.my_window import MyWindow
from widget.info_box import InfoBox
from widget.db_init.peewee import testModel229_dp
from widget.db_init.configuration import sql_configuration as LM
from widget.db_init.sqlUtils.mysqlUtils import MySqlOp
import _thread
import time
import xlrd
import xlwt


class MySqlInitPage(MyWindow):
    '''
    mysql配置页面（导入页面的子页面）
    '''
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setAttribute(Qt.WA_StyledBackground, False)
        # 窗口置顶
        # self.setWindowFlag(Qt.WindowStaysOnTopHint)
        self.setWindowModality(Qt.ApplicationModal)
        # 父窗口实例对象
        self.my_parent_window = kwargs['my_parent']
        # 窗口标题
        self.label_title = QLabel(self)
        self.label_title.resize(230, 40)
        self.label_title.setText('导入目标配置')
        self.label_title.move(10, 5)

        # 加载基本选项卡
        self.setup_ui()
        # 加载表格
        self.init_table()
        # 加载常规按钮（确定取消）
        self.init_common_btn()

    def setup_ui(self):
        '''
        加载三个选择框，用于定位数据表
        :return:
        '''
        # 选择服务器label -------------------------------------------------
        self.label1 = QLabel(self)
        self.label1.setText('选择服务器：')
        self.label1.move(50, 80)
        # 服务器下拉选择框
        # 数据来源类型下拉选择
        self.combo1 = QComboBox(self)
        self.combo1.setView(QListView())  # 通过setView和全局qss设置行高
        self.combo1.addItems(key for key in LM)
        self.combo1.setFixedWidth(120)
        self.combo1.move(150, 80)

        # 选择数据库label -------------------------------------------------
        self.label2 = QLabel(self)
        self.label2.setText('选择数据库：')

        self.label2.move(300, 80)
        # 数据库下拉选择框
        self.combo2 = QComboBox(self)
        self.combo2.setView(QListView())  # 通过setView和全局qss设置行高
        self.server_name = self.combo1.currentText()
        self.combo2.addItems(key for key in LM[self.server_name]['db_name'])
        self.combo2.setFixedWidth(120)
        self.combo2.move(400, 80)

        # 选择表label -------------------------------------------------
        self.label3 = QLabel(self)
        self.label3.setText('选择表：')
        self.label3.move(550, 80)

        # 表下拉选择框
        self.combo3 = QComboBox(self)
        self.combo3.setView(QListView())  # 通过setView和全局qss设置行高
        self.db_name = self.combo2.currentText()
        if self.server_name and self.db_name:
            mop = MySqlOp(host=self.server_name, db_name=self.db_name)
            table_list = mop.select("""show tables""")
            print(table_list)
            self.combo3.addItems(key[0] for key in table_list)
            self.combo3.setFixedWidth(120)
            self.combo3.move(620, 80)

        self.btn1 = QPushButton(self)
        self.btn1.move(770, 78)
        self.btn1_flag = True
        self.btn1.setText("全选字段")
        # 全选字段按钮绑定事件
        def table_operate():
            '''
            全选数据表中的字段
            :return:
            '''
            # 如果 btn1_flag 为True就为所有的选框打钩，否则取消打钩（btn1_flag初始化的时候为 True）
            if self.btn1_flag:
                for i in range(self.table1.rowCount()):
                    self.table1.cellWidget(i, 3).setCheckState(Qt.Checked)
            else:
                for i in range(self.table1.rowCount()):
                    self.table1.cellWidget(i, 3).setCheckState(Qt.Unchecked)
            # btn1_flag 取反
            self.btn1_flag = not self.btn1_flag

        self.btn1.clicked.connect(table_operate)

        # 数据库监听服务器，服务器改变就切换数据库 -------------------------------------------------
        def init_db_name():
            '''
            从配置文件中获取当前服务器的数据库队列 并载入 combo2选择框中
            :return:
            '''
            server_name = self.combo1.currentText()
            print(server_name)
            self.combo2.clear()
            self.combo2.addItems(key for key in LM[server_name]['db_name'])
        self.combo1.currentIndexChanged.connect(init_db_name)

        # 表监听数据库，数据库改变就切换表 -------------------------------------------------
        def init_table_name():
            '''
            查询 mysql，获取当前数据库中的所有表名 并载入 combo3选择框中
            :return:
            '''
            self.db_name = self.combo2.currentText()
            self.combo3.clear()
            if self.server_name and self.db_name:
                print(self.server_name, self.db_name)
                mop = MySqlOp(host=self.server_name, db_name=self.db_name)
                table_list = mop.select("""show tables""")
                print(table_list)
                self.combo3.addItems(key[0] for key in table_list)
        self.combo2.currentIndexChanged.connect(init_table_name)

    def init_table(self):
        '''
        加载数据表
        :return:
        '''
        self.table1 = QTableWidget(self)
        self.table1.resize(800, 300)
        self.table1.move(50, 150)
        # self.table1.setVerticalHeaderLabels(["第一列", "第二列"])
        # 设置表格的列数为4列
        self.table1.setColumnCount(4)
        # 刷新表格
        self.refresh()
        # 表格监听表，如果表选择框改变，那么刷新表格
        self.combo3.currentIndexChanged.connect(self.refresh)

    # 刷新表格
    def refresh(self):
        '''
        刷新表格的方法，此方法被绑定到 combo3上，combo3的值改变就会刷新表格，
        同时 combo3 绑定的 combo2， combo2绑定的 combo1，所以实际上形成了三级联动，
        也就是说 改变 服务器（combo1）、数据库（combo2）或者 表（combo3）中任意一个选框的的值，都会进行表格的刷新
        :return:
        '''
        # 获取选择框中的表名
        self.table_name = self.combo3.currentText()
        if self.server_name and self.db_name:
            mop = MySqlOp(host=self.server_name, db_name=self.db_name)
            # 查询 对应数据库下对应表的 字段名，字段类型，字段说明
            field_list = mop.select(
                """select COLUMN_NAME,DATA_TYPE,COLUMN_COMMENT from information_schema.COLUMNS where table_name = '{0}' and table_schema = '{1}'""".format(
                    self.table_name, self.db_name))
            # 第一条是主键id，该字段自动生成不用导入
            field_list = field_list[1:]
            # 设置表格行数为查询数据的长度
            self.table1.setRowCount(len(field_list))
            # self.table1.setRowHeight(0, 0)

            # 设置表格每列的宽度
            self.table1.setColumnWidth(0, 220)
            self.table1.setColumnWidth(1, 220)
            self.table1.setColumnWidth(2, 220)
            self.table1.setColumnWidth(3, 95)
            # print(field_list)
            # 填充字段
            self.table1.clear()
            self.table1.setHorizontalHeaderLabels(["字段名称", "数据类型", "字段说明", "是否导入"])

            for i, field in enumerate(field_list):
                for k, f_type in enumerate(field):
                    self.table1.setItem(i, k, QTableWidgetItem(f_type))
                self.table1.setCellWidget(i, 3, QCheckBox())
                self.table1.cellWidget(i, 3).setStyleSheet("margin-left: 40px;")

    def init_common_btn(self):
        '''
        底部的 确定 和 取消 按钮
        :return:
        '''
        # 确定按钮
        self.btn2 = QPushButton(self)
        self.btn2.setText("确定")
        self.btn2.move(620, 480)
        def field_get():
            self.my_parent_window.mysql_field_name_list = []
            for i in range(self.table1.rowCount()):
                if self.table1.cellWidget(i, 3).checkState():
                    field_name = '{0}[{1}]'.format(self.table1.item(i, 0).text(), self.table1.item(i, 1).text())
                    self.my_parent_window.mysql_field_name_list.append(field_name)
            print(self.my_parent_window.mysql_field_name_list)
            # 如果选择了字段，就关闭当前窗口， 否则给出提示，让用户重选
            if self.my_parent_window.mysql_field_name_list:
                self.close_btn.click()
            else:
                # 信息提示盒子，显示1秒
                self.info_box = InfoBox('至少选择一个字段')
                # self.info_box.setWindowFlag(Qt.WindowStaysOnTopHint)
                self.info_box.show()
                def show_1s(info_box):
                    '''
                    提示框展示一秒后销毁
                    :param info_box:
                    :return:
                    '''
                    time.sleep(1)
                    info_box.close()
                _thread.start_new_thread(show_1s, (self.info_box,))

                # killTimer 用于杀死定时器，传入对应定时器id
                # timer_obj.killTimer(timer_id)

            self.my_parent_window.daoru_input2.setText('mysql--{0}--{1}--{2}--{3}'.format(self.server_name, self.db_name, self.table_name, '不导入,' + ','.join(self.my_parent_window.mysql_field_name_list)))
        self.btn2.clicked.connect(field_get)

        # 取消按钮
        self.btn3 = QPushButton(self)
        self.btn3.setText("取消")
        self.btn3.move(720, 480)
        # 点击取消，触发右上角关闭按钮事件
        self.btn3.clicked.connect(self.close_btn.click)

    def keyPressEvent(self, QKeyEvent):  # 键盘某个键被按下时调用
        '''
        按下 ESC关闭当前页
        :param QKeyEvent:
        :return:
        '''
        # 参数1  控件
        if QKeyEvent.key() == Qt.Key_Escape:  # 判断是否按下了ESC键
            self.close_btn.click()